TalentSync

AI resume builder and ATS optimizer for job seekers. Tailored resumes, outreach, and interview prep from one profile.

React query integration

How React Query is integrated into the frontend application.

Repository layout#

React Query is initialized at the application boundary and consumed by feature-specific hooks and services:

  • Providers initialize the QueryClient with default caching and retry behavior.
  • Services encapsulate API calls and return typed responses.
  • Custom hooks wrap React Query primitives to expose domain-specific data fetching and mutations.
  • A toast utility integrates with mutations for user feedback.

Building blocks#

  • QueryClientProvider and default options:
  • Stale time is configured to treat data as fresh for a short duration.
  • Automatic retries are enabled for transient failures.
  • Window focus refetch is disabled to avoid unnecessary network activity.
  • API client:
  • Provides typed request helpers (get, post, put, patch, delete).
  • Handles query parameters, FormData, and JSON bodies.
  • Parses JSON responses and throws a structured ApiError on non-OK responses.
  • Distinguishes between network errors and server-side error messages.
  • Custom hooks:
  • useQuery wrappers for domain resources (e.g., dashboard, resume).
  • useMutation wrappers for write operations with optimistic updates and invalidation.
  • Integration with a toast utility for user feedback on success/error.

How it fits together#

The integration follows a layered pattern:

  • Application layer: Providers configure React Query globally.
  • Services layer: Typed API clients encapsulate HTTP requests and normalize responses.
  • Hooks layer: Domain-specific React Query hooks orchestrate reads/writes.
  • UI layer: Components consume hooks and render state.

Query client setup and provider#

  • Providers initializes a single QueryClient instance with defaultOptions:
  • staleTime controls freshness.
  • retry governs transient failure resilience.
  • refetchOnWindowFocus disabled to reduce background traffic.
  • Devtools are included for development inspection.

API client configuration and error handling#

  • Request builder supports method, headers, body, and query parameters.
  • Automatically sets Content-Type for JSON payloads and leaves it unset for FormData.
  • Response parsing and error normalization:
  • On non-OK responses, constructs a human-readable message from common error fields.
  • Throws a structured ApiError with status and data payload.
  • Catches unexpected errors and wraps them as ApiError with a generic message.

Custom hook patterns: queries#

  • useDashboard:
  • Defines a queryKey for dashboard data.
  • Fetches data via dashboardService and returns normalized data.
  • useResume:
  • Accepts an id and enables the query only when id is truthy.
  • Returns loading, error, and data states.

Custom hook patterns: mutations and optimistic updates#

  • useDeleteResume, useRenameResume, useUploadResume:
  • Use useMutation to perform write operations.
  • On success:
  • Invalidate related queries to refresh cached data.
  • Show a success toast.
  • On error:
  • Show a destructive toast with the error message.
  • useTailorResume, useGenerateLatex, useDownloadPdf:
  • Provide mutation functions for resume generation tasks.
  • useDownloadPdf bypasses the typed apiClient wrapper to handle raw Blob responses.

Caching strategies#

  • Freshness:
  • staleTime is configured to keep data fresh for a short period, balancing responsiveness with cache validity.
  • Invalidation:
  • After mutations, invalidateQueries is used to trigger refetch of affected query keys (e.g., [“dashboard”]).
  • Background refetch:
  • Enabled by default for most queries; window focus refetch is disabled to prevent unnecessary network activity.

Pagination and infinite queries#

  • Current implementation does not include pagination or infinite query patterns.
  • Recommendations for future implementation:
  • Use hasNextPage and pages for infinite queries.
  • Implement getNextPageParam and getPreviousPageParam for cursor-based pagination.
  • Combine with queryKey composition to scope caches per page.

[No sources needed since this section provides general guidance]

Real-time data synchronization#

  • No explicit real-time synchronization mechanisms are present in the current codebase.
  • Recommendations:
  • Use background refetch intervals for periodic updates.
  • Implement WebSocket or Server-Sent Events alongside React Query invalidations.
  • Consider selective invalidation of specific query keys to minimize network overhead.

[No sources needed since this section provides general guidance]

Dependencies#

The following diagram shows how components depend on each other across layers:

Performance#

  • Prefer targeted invalidation over broad cache clearing to minimize refetches.
  • Use enabled flags to defer queries until required (as seen with resume query).
  • Keep staleTime reasonable to balance freshness and bandwidth.
  • Avoid excessive retries for operations that should fail fast.
  • Use background refetch judiciously; disable window focus refetch for non-critical data.

[No sources needed since this section provides general guidance]

Troubleshooting#

Common issues:

  • Network errors:
  • The API client wraps unknown errors as ApiError with a generic message. Inspect the thrown error’s message and status to diagnose.
  • Server-side errors:
  • The API client extracts messages from common fields and throws a structured error. Log the status and data payload for debugging.
  • Mutation errors:
  • Use the onError callback in useMutation to display messages via the toast utility.
  • Query not updating after mutation:
  • Ensure invalidateQueries is called with the correct queryKey to trigger refetch.
  • Excessive refetches:
  • Adjust staleTime and retry settings in the QueryClient defaults.